package org.gw.building.ctrl;

import jxl.Workbook;
import jxl.write.Label;
import jxl.write.WritableSheet;
import jxl.write.WritableWorkbook;
import jxl.write.WriteException;
import jxl.write.biff.RowsExceededException;
import org.gw.building.model.StuInfo;
import org.gw.building.model.Term;
import org.gw.building.model.TermIntro;
import org.gw.building.model.TermStuApply;
import org.gw.building.repositories.StuInfoRepository;
import org.gw.building.repositories.TermRepository;
import org.gw.building.repositories.TermStuApplyRepositories;
import org.gw.building.util.FileHelper;
import org.gw.building.util.TrainUtil;
import org.gw.ylc.base.context.RequestContextHolder;
import org.gw.ylc.base.exception.RequestMessageException;
import org.gw.ylc.base.repositories.CommonRepository;
import org.gw.ylc.base.repositories.StudentRepository;
import org.gw.ylc.base.util.PermissionUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.stereotype.Controller;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.FileCopyUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Controller
@RequestMapping("term")
public class TermCtrl {
	@Autowired
	private TermRepository termRepository;
	@Autowired
	private TermStuApplyRepositories applyRepositories;
	@Autowired
	private StudentRepository studentRepository;
	@Autowired
	private CommonRepository commonRepository;
	@Autowired
	private StuInfoRepository stuInfoRepository;
	private Map<String, Term> currentMap = new HashMap<String, Term>();
	private long cacheTime;

	@RequestMapping("getCurrent")
	@ResponseBody
	public Term getCurrent(String trainType) {
		if ((System.currentTimeMillis() - cacheTime) > 180000) {
			currentMap.clear();
			cacheTime = System.currentTimeMillis();
		}
		Term term = currentMap.get(trainType);
		if (term == null) {
			term = termRepository.getCurrentTerm(trainType);
			currentMap.put(trainType, term);
		}
		return term;
	}

	///////////////////////////////////////////////////////////////////
	//
	// 维护期次
	//
	///////////////////////////////////////////////////////////////////
	/**
	 * 查询期次
	 * 
	 * @param name
	 *            名称
	 * @param openStu
	 *            是否开启允许学生申请
	 * @param status
	 *            开启状态
	 * @return
	 */
	@RequestMapping("queryTerms")
	@ResponseBody
	public Page<Term> queryTerms(String trainType, String name, Integer openStu, Integer status) {
		return termRepository.query(PermissionUtil.toLikeString(name), openStu, status, trainType,
				RequestContextHolder.get().getPageRequest());
	}

	@RequestMapping("getApplyCount")
	@ResponseBody
	public Object getApplyCount(String[] term, Integer status) {
		return applyRepositories.getCountByTermIdInAndStatus(term, status);
	}

	/**
	 * 添加期次
	 * 
	 * @param term
	 * @return
	 */
	@RequestMapping("addTerm")
	@ResponseBody
	@Transactional
	public Object addTerm(Term term, String intro) {
		currentMap.clear();
		termRepository.disableAll(term.getTrainType().getId());
		Term save = termRepository.save(term);
		TermIntro findOne = commonRepository.findOne("from TermIntro t where t.term=?1", save.getId());
		if (findOne == null) {
			findOne = new TermIntro();
			findOne.setTerm(save.getId());
		}
		findOne.setIntro(intro);
		commonRepository.save(findOne);
		return save;
	}

	/**
	 * 删除期次
	 * 
	 * @param term
	 * @return
	 */
	@RequestMapping("removeTerm")
	@ResponseBody
	public Object removeTerm(String id) {
		currentMap.clear();
		termRepository.delete(id);
		return "success";
	}

	/**
	 * 编辑期次
	 * 
	 * @param term
	 * @return
	 */
	@RequestMapping("updateTerm")
	@ResponseBody
	@Transactional
	public Object updateTerm(Term term, String intro) {
		currentMap.clear();
		termRepository.disableAll(term.getTrainType().getId());
		Term save = termRepository.save(term);
		TermIntro findOne = commonRepository.findOne("from TermIntro t where t.term=?1", save.getId());
		if (findOne == null) {
			findOne = new TermIntro();
			findOne.setTerm(save.getId());
		}
		findOne.setIntro(intro);
		commonRepository.save(findOne);
		return save;
	}

	/**
	 * 根据ID获取期次
	 * 
	 * @param term
	 * @return
	 */
	@RequestMapping("getTermById")
	@ResponseBody
	public Term getTermById(String id) {
		return termRepository.findOne(id);
	}

	///////////////////////////////////////////////////////////////////
	//
	// 申请期次
	//
	///////////////////////////////////////////////////////////////////
	/**
	 * 学生申请期次
	 * 
	 * @param termStuApply
	 * @return
	 */
	@RequestMapping("apply")
	@ResponseBody
	public Object apply(TermStuApply termStuApply) {
		termStuApply.setApplyTime(new Date());
		termStuApply.setUser(RequestContextHolder.get().getUser());
		// termStuApply.setTerm(termRepository.getCurrentTerm());
		termStuApply.setStatus(1);// 1为带院系审核，这里不需要草稿状态0
		return applyRepositories.save(termStuApply);
	}

	/**
	 * 学生个人的申请，已申请不能再次申请
	 * 
	 * @return
	 */
	@RequestMapping("getTermApply")
	@ResponseBody
	public Object getTermApply(String xh) {
		TermStuApply apply = applyRepositories.findOneByTermAndStudentXh(PermissionUtil.getFilteredStudentXh(xh));
		return apply;
	}

	/**
	 * 查询期次申请
	 * 
	 * @param xh
	 *            学号/姓名
	 * @param grade
	 *            年级
	 * @param department
	 *            院系
	 * @param major
	 *            专业
	 * @param isGB
	 *            是否团学干部
	 * @param applyTZS
	 *            是否申请团支书
	 * @param status
	 *            审核状态
	 * @return
	 */
	@RequestMapping("queryTermStuApply")
	@ResponseBody
	public Page<TermStuApply> queryTermStuApply(String xh, String grade, String department, String major, Integer isGB,
			Integer applyTZS, Integer status) {
		return applyRepositories.queryTermStuApply(PermissionUtil.toLikeString(xh), grade,
				PermissionUtil.getFilteredDepartmentId(department), major, isGB, applyTZS, null,
				TrainUtil.getFilteredStatusArray(status), RequestContextHolder.get().getPageRequest());
	}

	@RequestMapping("export")
	@ResponseBody
	public Object export(String xh, String grade, String department, String major, Integer isGB, Integer applyTZS,
			Integer status, HttpServletResponse response)
			throws FileNotFoundException, IOException, RowsExceededException, WriteException {
		Page<TermStuApply> applies = applyRepositories.queryTermStuApply(PermissionUtil.toLikeString(xh), grade,
				PermissionUtil.getFilteredDepartmentId(department), major, isGB, applyTZS, null,
				TrainUtil.getFilteredStatusArray(status), new PageRequest(0, Integer.MAX_VALUE));
		File tempFolder = FileHelper.getTempFolder("train_");
		String xlsFileName = "学员报名审核信息.xls";
		String xlsFilePath = tempFolder.getAbsolutePath() + "/" + xlsFileName;
		File xlsFile = new File(xlsFilePath);
		response.setContentType("application/octet-stream;charset=UTF-8");
		response.setHeader("Content-Disposition", "attachment; filename=" + URLEncoder.encode(xlsFileName, "UTF-8"));
		doExport(xlsFile, applies.getContent());
		OutputStream out = response.getOutputStream();
		FileCopyUtils.copy(new FileInputStream(xlsFile), out);
		out.flush();
		return null;
	}

	private final static DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm");

	/**
	 * <th>姓名</th>
	 * <th>性别</th>
	 * <th>学号</th>
	 * <th>年级</th>
	 * <th>院系</th>
	 * <th>专业</th>
	 * <th>学生类别</th>
	 * <th>提交时间</th>
	 * <th>状态</th>
	 * 
	 * @param xlsFile
	 * @param stus
	 * @throws IOException
	 * @throws RowsExceededException
	 * @throws WriteException
	 */
	private void doExport(File xlsFile, List<TermStuApply> stus)
			throws IOException, RowsExceededException, WriteException {
		WritableWorkbook book = null;
		String[] headers = { "姓名", "性别", "学号", "年级", "院系", "专业", "学生类别", "提交时间", "状态" };
		try {
			book = Workbook.createWorkbook(xlsFile);
			WritableSheet sheet = book.createSheet("学员信息报名审核信息", 0);
			/** 写header */
			for (int i = 0; i < headers.length; i++) {
				sheet.addCell(new Label(i, 0, headers[i]));
			}
			int row = 1;
			for (TermStuApply stu : stus) {
				sheet.addCell(new Label(0, row, stu.getUser().getName()));
				sheet.addCell(new Label(1, row, stu.getSexString()));
				sheet.addCell(new Label(2, row, stu.getUser().getUid()));
				sheet.addCell(new Label(3, row, stu.getUser().getGrade()));
				sheet.addCell(new Label(4, row, stu.getUser().getDepartment()));
				sheet.addCell(new Label(5, row, stu.getUser().getMajor()));
				sheet.addCell(new Label(6, row, ""));// TODO: 学生类别
				sheet.addCell(new Label(7, row, df.format(stu.getApplyTime())));
				sheet.addCell(new Label(8, row, stu.getStatusName()));
				row += 1;
			}
			book.write();
		} finally {
			if (book != null)
				try {
					book.close();
				} catch (WriteException e) {
					e.printStackTrace();
				} catch (IOException e) {
					e.printStackTrace();
				}
		}
	}

	/**
	 * 审核期次申请
	 * 
	 * @param id
	 *            申请ID
	 * @param action
	 *            通过/不通过
	 * @return
	 */
	@RequestMapping("examineTermStuApply")
	@ResponseBody
	public Object examineTermStuApply(String id, Integer action) {
		examineApply(id, action);
		return "success";
	}

	@RequestMapping("updateTermStuApply")
	@ResponseBody
	public Object updateTermStuApply(TermStuApply apply) {
		if (PermissionUtil.isSchoolAdmin()) {
			applyRepositories.save(apply);
			return "succ";
		}
		return null;
	}

	@Transactional
	private void examineApply(String id, Integer action) {
		TermStuApply apply = applyRepositories.findOne(id);
		if (RequestContextHolder.get().getUser().getType() != apply.getStatus()) {
			throw new RequestMessageException("权限错误");
		}
		if (action == 1) {
			// 审核通过
			apply.setStatus(apply.getStatus() + 1);
		} else {
			// 审核不通过
			apply.setStatus(-1);
		}
		applyRepositories.save(apply);
		if (apply.getStatus() == 3) {
			StuInfo info = new StuInfo();
			info.setUser(apply.getUser());
			info.setLxfs(apply.getLxfs());
			info.setPhone(apply.getPhone());
			info.setQq(apply.getQq());
			info.setZw(apply.getZw());
			info.setJrfs(0);
			info.setStatus(0);
			info.setSex(apply.getSex());
			info.setXq(apply.getXq());
			info.setSfwtzs(0);
			info.setTerm(apply.getTerm());
			info.setSfsqtzs(apply.getIssqtzs());
			stuInfoRepository.save(info);
		}
	}

	/**
	 * 批量审核期次申请
	 * 
	 * @param ids
	 *            多个申请ID
	 * @param action
	 *            通过/不通过
	 * @return
	 */
	@RequestMapping("examineTermStuApplies")
	@ResponseBody
	@Transactional
	public Object examineTermStuApplies(String[] ids, Integer action) {
		for (String id : ids) {
			examineApply(id, action);
		}
		return "success";
	}
}
